package com.syyo.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.syyo.admin.domain.entity.DeptEntity;
import com.syyo.admin.domain.entity.UserEntity;
import com.syyo.admin.domain.req.DeptReq;
import com.syyo.admin.domain.resp.DeptResp;
import com.syyo.admin.mapper.DeptMapper;
import com.syyo.admin.mapper.UserMapper;
import com.syyo.admin.service.DeptService;
import com.syyo.admin.utils.TreeUtils;
import com.syyo.common.enums.ResultEnum;
import com.syyo.common.exception.SysException;
import com.syyo.common.utils.MyListUtils;
import com.syyo.common.utils.MyStringUtils;
import org.apache.catalina.User;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 部门表 服务实现类
 * </p>
 *
 * @author wang
 * @since 2020-08-20
 */
@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, DeptEntity> implements DeptService {

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private UserMapper userMapper;

    @Override
    @Transactional
    public int add(DeptReq req) {
        DeptEntity entity = new DeptEntity();
        List<Integer> pidList = req.getPidList();
        Integer pid = MyStringUtils.getPid(pidList);
        String pids = MyStringUtils.getPids(pidList);
        Integer rank = MyStringUtils.getRank(pidList);
        entity.setPid(pid);
        entity.setPids(pids);
        entity.setRank(rank);
        entity.setDeptName(req.getDeptName());
        LocalDateTime now = LocalDateTime.now();
        entity.setUpdateTime(now);
        entity.setCreateTime(now);
        int insert = deptMapper.insert(entity);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_80031.getCode(), ResultEnum.E_80031.getMessage());
        }
        return insert;
    }

    @Override
    @Transactional
    public int del(Integer id) {
        // 判断有没有关联的数据
        Integer count = userMapper.selectCount(new QueryWrapper<UserEntity>().eq("dept_id", id));
        if (count > 0) {
            throw new SysException(ResultEnum.E_70001.getCode(), ResultEnum.E_70001.getMessage());
        }
        // 判断有没有子部门
        Integer count1 = deptMapper.selectCount(new QueryWrapper<DeptEntity>().eq("pid", id));
        if (count1 > 0) {
            throw new SysException(ResultEnum.E_80037.getCode(), ResultEnum.E_80037.getMessage());
        }

        int insert = deptMapper.deleteById(id);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_80032.getCode(), ResultEnum.E_80032.getMessage());
        }
        return insert;
    }

    @Override
    @Transactional
    public int edit(DeptReq req) {
        DeptEntity entity = new DeptEntity();
        List<Integer> pidList = req.getPidList();
        Integer pid = MyStringUtils.getPid(pidList);
        String pids = MyStringUtils.getPids(pidList);
        Integer rank = MyStringUtils.getRank(pidList);
        DeptEntity dept = deptMapper.selectById(req.getDeptId());
        // 当前部门层级不能选择自己
        if (dept.getDeptId().equals(pid)){
            throw new SysException(ResultEnum.E_80036.getCode(),ResultEnum.E_80036.getMessage());
        }
        // 当前部门层级不能选择自己的子级
        List<Integer> ziList = deptMapper.getChildren(req.getDeptId());
        if (MyListUtils.isNotEmpty(ziList) && ziList.contains(pid)){
            throw new SysException(ResultEnum.E_80036.getCode(),ResultEnum.E_80036.getMessage());
        }
        entity.setDeptId(req.getDeptId());
        entity.setDeptName(req.getDeptName());
        LocalDateTime now = LocalDateTime.now();
        entity.setCreateTime(now);
        if (dept.getPid().equals(pid)){
            // 当该部门的pid和传来的pid一样时，表示只是修改名称
            int insert = deptMapper.updateById(entity);
            if (insert != 1) {
                throw new SysException(ResultEnum.E_80033.getCode(), ResultEnum.E_80033.getMessage());
            }
            return insert;
        }

        // 当该部门的pid和传来的不一样时，既修改名称，又修改层级
        entity.setPid(pid);
        entity.setPids(pids);
        entity.setRank(rank);
        int insert = deptMapper.updateById(entity);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_80033.getCode(), ResultEnum.E_80033.getMessage());
        }

        di_gui_dept(req.getDeptId(),pids,rank,now);
        return insert;
    }

    private void di_gui_dept(Integer deptId, String pids, Integer rank, LocalDateTime date) {
        List<Integer> ziList = deptMapper.nextZiDeptById(deptId);
        if (MyListUtils.isNotEmpty(ziList)) {
            for (Integer ziDeptId : ziList) {
                // 修改子部门
                DeptEntity sysDept = new DeptEntity();
                sysDept.setDeptId(ziDeptId);
                sysDept.setPid(deptId);
                String newpids = "";
                if ("0".equals(pids)){
                    newpids = deptId + "";
                }else {
                    newpids = pids + "," + deptId;
                }
                sysDept.setPids(newpids);
                int newrank = rank + 1;
                sysDept.setRank(newrank);
                sysDept.setUpdateTime(date);
                int i = deptMapper.updateById(sysDept);
                if (i != 1) {
                    throw new SysException(ResultEnum.E_10003.getCode(),ResultEnum.E_10003.getMessage());
                }
                // 调自己
                di_gui_dept(ziDeptId,newpids,newrank,date);
            }
        }
    }

    @Override
    public DeptResp findOne(Integer id) {
        DeptEntity sysDept = deptMapper.selectById(id);
        String pids = sysDept.getPids();
        List<Integer> list = MyStringUtils.stringToList(pids);
        DeptResp deptResp = new DeptResp();
        BeanUtils.copyProperties(sysDept,deptResp);
        deptResp.setPidList(list);
        return deptResp;
    }

    @Override
    public List<DeptEntity> tree() {
        List<DeptEntity> list = deptMapper.selectList(null);
        return TreeUtils.listToDeptTree(list);
    }
}
